package i18n.adapter;

import i18n.enums.language.ChineseEnum;
import i18n.enums.language.EnglishEnum;
import i18n.enums.I18nPrefixFieldEnum;
import i18n.enums.language.EnumGetValue;
import org.springframework.stereotype.Component;

import java.util.EnumSet;

@Component
public class I18nAcceptLanguageAdapter implements AcceptLanguageAdapterInterface {

    /**
     * 通过用户端发送的语言字段，转换成指定的可使用国际化前缀
     *
     * @param language 请求头 Accept-Language 参数
     * @return 指定 Bean 实体对应的国际化前缀枚举类型
     */
    @Override
    public I18nPrefixFieldEnum convert(String language) {
        I18nPrefixFieldEnum result = I18nPrefixFieldEnum.DEFAULT;
        if (language != null) {
            if (containsLanguage(ChineseEnum.enums, language)) {
                result = I18nPrefixFieldEnum.CHINESE;
            } else if (containsLanguage(EnglishEnum.enums, language)) {
                result = I18nPrefixFieldEnum.ENGLISH;
            } else { //其它语言，一律设置英语
                result = I18nPrefixFieldEnum.ENGLISH;
            }
        }
        return result;
    }

    /**
     * 因为设计截取时比较简单，浏览器传递过来的参数是多组的，且可以选择多种，而且还有权重，这里就直接截取开头
     * 如：Accept-Language: zh-CN,zh;q=0.9,en-US,en;q=0.8
     * 解释：
     *      zh-CN: 表示首选的语言是简体中文（中国大陆）。
     *      zh;q=0.9: 表示其次选项是中文，权重为0.9。这里没有特定指定地区，可以根据浏览器和操作系统的设置而定。
     *      en-US: 表示再次选项是美国英语。
     *      en;q=0.8: 表示最后选项是英语，权重为0.8。
     *
     * @param es 枚举类里的饿汉式全部枚举值
     * @param language Accept-Language 参数，用户端是可以指定对应显示设置枚举常量的前缀字段的，如 english
     * @return 是否包含前缀值
     * @param <T> 枚举类型且 EnumGetValue 类型
     */
    private <T extends Enum<T> & EnumGetValue> boolean containsLanguage(EnumSet<T> es, String language) {
        language = language.trim();
        boolean result = false;
        for (T e : es) {
            if (language.startsWith(e.getValue()) || //判断前缀
                language.startsWith(e.getValue().toLowerCase()) || //小写
                language.startsWith(e.getValue().toUpperCase())) { //大写
                result = true;
                break;
            }
        }
        return result;
    }

}
